package com.sudworth.repository.network.okhttp;


import android.content.SharedPreferences;

import com.jeremyliao.liveeventbus.LiveEventBus;

import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.EOFException;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.charset.UnsupportedCharsetException;
import java.util.List;

import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import timber.log.Timber;

public class NetWorkInterceptor implements Interceptor {

    private SharedPreferences mSp;

    public NetWorkInterceptor(SharedPreferences sp) {
        this.mSp = sp;
    }

    private static final Charset UTF8 = StandardCharsets.UTF_8;

    private boolean bodyEncoded(Headers headers) {
        String contentEncoding = headers.get("Content-Encoding");
        return contentEncoding != null && !contentEncoding.equalsIgnoreCase("identity");
    }

    private void saveSession(Headers headers) {
        List<String> cookies = headers.values("Set-Cookie");
        if(cookies.isEmpty()) return;
        String session = cookies.get(0);
        String sessionid = session.substring(0,session.indexOf(";"));
        mSp.edit().putString("session", sessionid).apply();
    }

    @NotNull
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Response response = chain.proceed(request);
        Headers headers = response.headers();
        saveSession(headers);
        ResponseBody responseBody = response.body();
        assert responseBody != null;
        long contentLength = responseBody.contentLength();

        if (!bodyEncoded(response.headers())) {
            BufferedSource source = responseBody.source();
            source.request(Long.MAX_VALUE); // Buffer the entire body.
            Buffer buffer = source.buffer();

            Charset charset = UTF8;
            MediaType contentType = responseBody.contentType();
            if (contentType != null) {
                try {
                    charset = contentType.charset(UTF8);
                } catch (UnsupportedCharsetException e) {
                    return response;
                }
            }

            if (!isPlaintext(buffer)) {
                return response;
            }

            if (contentLength != 0) {
                assert charset != null;
                String result = buffer.clone().readString(charset);
                Timber.d(" response.url():%s", response.request().url());
                Timber.d(" response.body():%s", result);
                try {
                    JSONObject jsonObject = new JSONObject(result);
                    String code = jsonObject.optString("code");
                    if("10001".equals(code)) {
                        //强制退出
                        LiveEventBus.get("event_account_error", String.class).broadcast(code);
                    }
                } catch (JSONException e) {
                    //不做任何处理
                }
                //得到所需的string，开始判断是否异常
                //***********************do something*****************************
            }
        }

        return response;
    }

    private static boolean isPlaintext(Buffer buffer) throws EOFException {
        try {
            Buffer prefix = new Buffer();
            long byteCount = buffer.size() < 64 ? buffer.size() : 64;
            buffer.copyTo(prefix, 0, byteCount);
            for (int i = 0; i < 16; i++) {
                if (prefix.exhausted()) {
                    break;
                }
                int codePoint = prefix.readUtf8CodePoint();
                if (Character.isISOControl(codePoint) && !Character.isWhitespace(codePoint)) {
                    return false;
                }
            }
            return true;
        } catch (EOFException e) {
            return false; // Truncated UTF-8 sequence.
        }
    }
}
